package com.darchrow.bio;

import com.google.common.util.concurrent.ThreadFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.*;

/**
 * @author mdl
 * @date 2020/4/29 13:58
 */
public class BioServerMultiThread2 {

    public static void main(String[] args) {
        int port = 8080;
        // 服务端
        ServerSocket server = null;
        // 服务端对象
        Socket socket = null;

        InputStream inputStream = null;
        OutputStream outputStream = null;

        ExecutorService executorService = Executors.newFixedThreadPool(1000);
        // 客户端连接过多，超过1000，越来越多的数据加入到LinkedBlockingQueue，资源会耗尽

        try {
            server = new ServerSocket(port);
            while (true) {
                // 没有客户端连接的时候，将阻塞在这里等待客户端三次握手
                socket = server.accept();

                executorService.submit(new SocketHandle(socket));
            }


        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    static class SocketHandle implements Runnable {

        private Socket socket;

        public SocketHandle(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            // 客户端连接上后，可以获取到客户端的请求流
            System.out.println(Thread.currentThread().getName() + "开始处理请求数据");
            InputStream inputStream = null;
            OutputStream outputStream = null;
            try {
                inputStream = socket.getInputStream();
                // 读请求数据
                int len = 0;
                byte[] req = new byte[1024];

                // read：这个地方，如果当前客户单未结束，一直阻塞在这里，其他客户端将无法accept
                // 每次读1024字节
                while ((len = inputStream.read(req)) > 0) {
                    System.out.println("req:" + new String(req, 0, len));
                    // 开始业务处理
                    outputStream = socket.getOutputStream();
                    outputStream.write("res".getBytes());
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


}
